package com.iot.tcp;

import com.iot.compont.GatewayServerEnum;
import com.iot.compont.ServerNetwork;
import com.iot.gateway.GatewayEntity;
import com.iot.messaage.FromDeviceMessageContext;
import com.iot.network.TcpDeviceSession;
import com.iot.network.WebSocketDeviceSession;
import com.iot.test.TestDeviceMessageDecoder;
import io.vertx.core.Vertx;
import io.vertx.core.net.NetServer;
import io.vertx.core.net.NetSocket;
import io.vertx.core.net.SocketAddress;
import reactor.core.Disposable;
import reactor.core.scheduler.Schedulers;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 */
public class TcpServerNetwork implements ServerNetwork {

    private NetSocket netSocket;
    private Vertx vertx;
    List<NetServer> instances;
    private Disposable legalityChecker;

//    String networkType = GatewayServerEnum.TCP.name();

    @Override
    public ServerNetwork createServer(GatewayEntity gatewayEntity) {
        vertx = Vertx.vertx();
        int instance = Math.max(2, Runtime.getRuntime().availableProcessors());
        instances = new ArrayList<>(instance);
        SocketAddress socketAddress = SocketAddress.inetSocketAddress(gatewayEntity.getProd(), gatewayEntity.getHost());
        for (int i = 0; i < instance; i++) {
            instances.add(vertx.createNetServer());
        }
        for (NetServer netServer : instances) {
            netServer.connectHandler(this::handleConnection);
            vertx.nettyEventLoopGroup().execute(() -> netServer.listen(socketAddress, result -> {
                        if (result.succeeded()) {

                        } else {

                        }
                    })
            );
        }

        return this;
    }

    @Override
    public Runnable cloneServer() {
        return null;
    }

    public void handleConnection(NetSocket netSocket) {
        this.netSocket = netSocket;
        netSocket.handler(buffer -> {
            String reportContext = buffer.toString();
            System.out.println(reportContext);

            TcpDeviceSession session=new TcpDeviceSession(netSocket);
            TestDeviceMessageDecoder testDeviceMessageDecoder=new TestDeviceMessageDecoder();
            testDeviceMessageDecoder.decode(FromDeviceMessageContext.of(session));


            legalityChecker.dispose(); // 先取消之前的定时任务
            legalityChecker = Schedulers.parallel()
                    .schedule(this::closeSocket, 10, TimeUnit.SECONDS);
        });

        legalityChecker = Schedulers
                .parallel()
                .schedule(this::closeSocket, 10, TimeUnit.SECONDS);
    }

    public void closeSocket() {
        this.netSocket.close();
        System.out.println("断开当前连接");
    }

}
